/* 
相当于Vue
*/
function MVVM(options) {

    // 将配置对象保存到vm上和data上
    this.$options = options;
    // 将data对象保存到vm上和
    var data = this._data = this.$options.data;
    var me = this;

    // 遍历data中每个属性, 并对每个属性都实现数据代理
    Object.keys(data).forEach(function(key) {
        // 对指定属性名的属性实现数据代理
        me._proxyData(key); // msg
    });

    this._initComputed();

    observe(data, this);

    // 创建一个编译对象
    this.$compile = new Compile(options.el || document.body, this)
}

MVVM.prototype = {
    constructor: MVVM,
    $watch: function(key, cb, options) {
        new Watcher(this, key, cb);
    },

    _proxyData: function(key) {
        var me = this;
        // 给mv添加带getter/setter属性
        Object.defineProperty(me, key, {
            configurable: false,
            enumerable: true,
            // 当vm.xxx读取数据调用返回data中对应名称的属性值
            get: function proxyGetter() {
                return me._data[key];
            },
            // 当vm.xxx = value时, 将最新值保存到data对应名称的属性上
            set: function proxySetter(newVal) {
                me._data[key] = newVal;
            }
        });
    },

    _initComputed: function() {
        var me = this;
        var computed = this.$options.computed;
        if (typeof computed === 'object') {
            Object.keys(computed).forEach(function(key) {
                Object.defineProperty(me, key, {
                    get: typeof computed[key] === 'function' 
                            ? computed[key] 
                            : computed[key].get,
                    set: function() {}
                });
            });
        }
    }
};